package com.hao.tool.web.module.fileInfo.controller;

import cn.hutool.extra.ftp.Ftp;
import com.hao.tool.common.constant.Commons;
import com.hao.tool.common.entity.LayResponse;
import com.hao.tool.extra.cloud.module.ali.AliCloudManager;
import com.hao.tool.extra.cloud.module.ali.entity.AlCosResult;
import com.hao.tool.web.common.constant.LayPage;
import com.hao.tool.web.component.exception.ErrorEnum;
import com.hao.tool.web.component.exception.ErrorPageException;
import com.hao.tool.web.component.properties.FTPProjectProperties;
import com.hao.tool.web.component.properties.PropertiesInfo;
import com.hao.tool.common.enums.ShortEnum;
import com.hao.tool.common.enums.StorageTypeEnum;
import com.hao.tool.web.module.base.entity.ShortInfo;
import com.hao.tool.web.module.base.service.ShortInfoService;
import com.hao.tool.web.module.fileInfo.entity.FileInfo;
import com.hao.tool.web.module.fileInfo.service.FileInfoService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * description
 *
 * @author RuiHaoZ on GZ.cmhk
 * @date 2019-11-22 21:46
 */
@RestController
@RequestMapping("/rest/file")
public class FileInfoRestController {
    @Autowired
    private FileInfoService fileInfoService;
    @Autowired
    private FTPProjectProperties ftpProperties;
    @Autowired
    private ShortInfoService shortInfoService;
    @Autowired
    private PropertiesInfo propertiesInfo;


    @GetMapping("/list")
    public LayPage list(FileInfo fileInfo, LayPage<FileInfo> page) {
        return fileInfoService.pageByInfo(page, fileInfo);
    }

    @GetMapping("/down/{fileId}")
    public void downInfo(@PathVariable String fileId,
                         HttpServletResponse response) throws Exception {
        FileInfo fileInfo = fileInfoService.getById(fileId);

        if (fileInfo == null) {
            throw new ErrorPageException(ErrorEnum.NOT_FOUNT, "文件内容不存在");
        }
        String storageType = fileInfo.getStorageType();
        if (StorageTypeEnum.TX_COS.getCode().equals(storageType)) {

            throw new ErrorPageException(ErrorEnum.NOT_FOUNT, "文件存储类型支持");
        } else if (StorageTypeEnum.AL_COS.getCode().equals(fileInfo.getStorageType())) {
            AlCosResult alCosResult = AliCloudManager.buildCos(null, null)
                    .downFile(fileInfo.getFilePath(), propertiesInfo.getLocalFileRootDir() + fileInfo.getFilePath());
            File file = alCosResult.getDownFile();

            response.setHeader("content-disposition", "attachment;fileName="
                    + URLEncoder.encode(fileInfo.getFileName(), "UTF-8"));
            OutputStream outputStream = response.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(file);
            IOUtils.copy(fileInputStream, outputStream);
            outputStream.close();

        } else if (StorageTypeEnum.FTP.getCode().equals(storageType)) {
            String downFilePath = fileInfo.getFilePath();
            Ftp ftp = new Ftp(ftpProperties.getFtpIp(), ftpProperties.getFtpPort(),
                    ftpProperties.getFtpUsername(), ftpProperties.getFtpPassword());
            boolean isExist = ftp.existFile(downFilePath);
            if (!isExist) {
                throw new ErrorPageException(ErrorEnum.NOT_FOUNT, "FTP文件不存在");
            } else {
                response.setHeader("content-disposition", "attachment;fileName="
                        + URLEncoder.encode(fileInfo.getFileName(), "UTF-8"));
                int lastLine = downFilePath.lastIndexOf("/");
                String filePathPreFix = downFilePath.substring(0, lastLine);
                String fileName = downFilePath.substring(lastLine + 1);
                OutputStream outputStream = response.getOutputStream();
                ftp.download(filePathPreFix, fileName, outputStream);
                outputStream.close();
            }
        } else if (StorageTypeEnum.LOCAL.getCode().equals(storageType)) {
            String filePathPreFix = fileInfo.getFilePath();
            File localFile = new File(filePathPreFix);
            if (!localFile.exists()) {
                throw new ErrorPageException(ErrorEnum.NOT_FOUNT, "本地文件不存在");
            }
            response.setHeader("content-disposition", "attachment;fileName="
                    + URLEncoder.encode(fileInfo.getFileName(), "UTF-8"));
            OutputStream outputStream = response.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(localFile);
            IOUtils.copy(fileInputStream, outputStream);
            outputStream.close();
        }
    }

    @PostMapping("/add/{storageType}")
    public LayResponse uploadImageToCos(@PathVariable String storageType, MultipartFile file,
                                        HttpServletRequest request) throws Exception {
        if (file == null) {
            throw new Exception("文件不存在");
        }
        StorageTypeEnum typeEnum = StorageTypeEnum.getByCode(storageType);
        if (typeEnum == null) {
            throw new Exception("存储类型不正确");
        }
        String userName = (String) request.getAttribute(Commons.SUB_KEY);
        userName = StringUtils.isBlank(userName) ? "anonymous" : userName;
        FileInfo fileInfo = fileInfoService.uploadAndSaveFile(file, userName, storageType);
        return LayResponse.builder().code(200).msg("").data(fileInfo).build();
    }


    @PostMapping("/addShort")
    public LayResponse shortEdit(String longId, String shortId,
                                 HttpServletRequest request) {
        String userName = (String) request.getAttribute(Commons.SUB_KEY);
        ShortInfo shortInfo = new ShortInfo(shortId, longId);
        shortInfo.setShortType(ShortEnum.FILE.getCode());
        shortInfo.setCreateUser(userName);
        shortInfoService.saveOrUpdate(shortInfo);
        return LayResponse.builder().code(200).msg("").data(shortInfo).build();
    }


}
